#ifndef CAMEYE_H_
#define CAMEYE_H_

#include "precom.h"
#include "ModelStructs.h"

class CamEye
{
private:
	bool				m_isInvertActual;
	fmath::matrix44		m_projection;
	fmath::matrix44		m_axis;
	fmath::matrix44		m_invProj;
	fmath::vector3		m_trans;
	fmath::vector3		m_adjustTrans;
	float				m_zoom;
	float				m_modelNormalZoomRem;

	void RotateBy(float a_angle, unsigned int a_axisInd);
protected:
	void ExpandBox(Box& a_box, float a_margPercent) const;
public:
	CamEye(GLuint a_width = 100, GLuint a_height = 100);
	virtual ~CamEye() {}

	void ChangeToPerspective(const Box& a_box, GLuint a_width, GLuint a_height);
	void ChangeToPerspective(GLuint a_width, GLuint a_height);
	void ChangeToOrtho(GLuint a_width, GLuint a_height);
	void AdjustCamToBox(const Box& a_bbox);

	inline void ExtraZoomOn() {
		m_zoom *= 1.02f;
	}
	inline void ExtraZoomOff() {
		m_zoom *= 1.f/1.02f;
	}
	inline void ZoomIn()
	{ 
		m_zoom *= 1.01f; 
		if(m_zoom > 4.0f * m_modelNormalZoomRem)
			m_zoom = 4.0f * m_modelNormalZoomRem;
	}
	inline void ZoomOut()
	{ 
		m_zoom /= 1.01f; 
		if(m_zoom < 0.125f * m_modelNormalZoomRem)
			m_zoom = 0.125f * m_modelNormalZoomRem;
	}
	inline void ResetZoom()
	{ m_zoom = m_modelNormalZoomRem; }
	inline void ResetView()
	{ m_projection.identity(); }
	inline void Move(float a_x, float a_y, float a_z)
	{ 
		m_projection = fmath::TranslateMatrix44(a_x, a_y, a_z) * m_projection; 
	}
	inline void RotateX(float a_angle) 
	{ RotateBy(a_angle, 0); }
	inline void RotateY(float a_angle) 
	{ RotateBy(a_angle, 1); }
	inline void RotateZ(float a_angle) 
	{ RotateBy(a_angle, 2); }
	inline void MoveInZ(float a_distance)
	{ Move(0.f, 0.f, a_distance); }
	inline void MoveInX(float a_distance)
	{ Move(a_distance, 0.f, 0.f); }
	inline void MoveInY(float a_distance)
	{ Move(0.f, a_distance, 0.f); }
	inline void Rotate(float a_xAng, float a_yAng, float a_zAng)
	{ RotateBy(a_xAng, 0); RotateBy(a_yAng, 1); RotateBy(a_zAng, 2); }

	fmath::matrix44& GetInvertProj();
	void ApplyCamera();
	void DrawAxis();
};

#endif //CAMEYE_H_